home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
pc
/
files
/
t_jnos
/
j109lxa4.tgz
/
j109lxa4.tar
/
expire.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-04
|
11KB
|
428 lines
/* Expire old messages.
* Inspired by 'expire.c' by Bernie Roehl.
* Substantially rewritten for integration into KA9Q NOS,
* WG7J v1.01 and later
* by Johan. K. Reinalda, WG7J/PA3DIS, March/April 92
*
* Old bid expiry by WG7J, March 92
*/
/* 'expire n' sets the expire interval for n hours.
* Each time the timer goes off, a new process is started,
* that expires the old messages...
*
* The control file '~/spool/expire.dat' contains lists of
* filename age
* where 'filename' is the name of the .txt file under '~/spool/mail'
* containing the messages (without the .txt extension) and where
* age = maximum age of message in days.
*
* If no age is given, the default age is 21 days.
*
* filename can be extended into subdirectories, and can have either
* '/', '\' or '.' to indicate subdirectories.
* filename should NOT have the ending '.txt'
*/
#include <stdio.h>
#include <stdlib.h>
#ifdef MSDOS
#include <dir.h>
#include <dos.h>
#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "global.h"
#include "config.h"
#include "timer.h"
#include "proc.h"
#include "bm.h"
#include "files.h"
#include "socket.h"
#ifdef linux
extern int unlink __ARGS((char *));
#endif
#ifdef UNIX
#define mktime j_mktime
#endif
#ifndef __BORLANDC__
time_t mktime(struct tm *);
/* If you're using BC++ 2.0 or higher, you don't need this,
* but TCC 2.0 doesn't have it... (But, TC++ v1.01 does)
*/
/* Simple emulation of the mktime() call (sort-of works :-) )
* doesn't do any error checking,
* no timezone adjustments or value adjustments
* Simply 'sort-a' calculates the number of seconds since 1970 - WG7J
*/
time_t
mktime(t)
struct tm *t;
{
static int total[12]={0,31,59,90,120,151,181,212,243,273,304,334};
int years;
int leapyears;
int days;
/* time count start at jan 1, 1970, 00:00 hrs */
years = t->tm_year - 70;
/* adjust for leap-years */
leapyears = (years + 2) / 4;
if (!((years+70) & 3) && (t->tm_mon < 2))
--leapyears; /* no extra day until 3/1 or after */
days = years*365L + leapyears + total[t->tm_mon] + (t->tm_mday-1);
return( days*86400L + t->tm_hour*3600L + t->tm_min*60L + t->tm_sec);
}
#endif
/* Include the rest in #ifdef's, so we don't pull in the whole module
* when we only have AT defined and NOT EXPIRE !
* (since these are the two modules that needs the surrogate mktime()
* if compiling with Turbo C 2.0 )
*/
#ifdef EXPIRY
/* Default expiry values: */
#define DEFAULT_AGE 21 /* 21 days from arrival date */
#define MSPHOUR (1000L*60L*60L)
static struct timer Expiretimer;
static void Expireprocess __ARGS((int a,void *v1,void *v2));
static void Expiretick __ARGS((void *));
static void expire __ARGS((char *,int));
static void Oldbidtick __ARGS((void *p));
int
#ifdef PROTOTYPES
doexpire(int argc,char **argv,void *p)
#else
doexpire(argc,argv,p)
int argc;
char *argv[];
void *p;
#endif
{
if(argc < 2) {
tprintf("timer: %lu/%lu hrs\n",
read_timer(&Expiretimer)/MSPHOUR,
dur_timer(&Expiretimer)/MSPHOUR);
return 0;
}
if(*argv[1] == 'n') {
Expiretick(NULL);
return 0;
}
/* set the timer */
stop_timer(&Expiretimer); /* Just in case */
Expiretimer.func = (void (*)__FARGS((void*)))Expiretick;/* what to call on timeout */
Expiretimer.arg = NULL; /* dummy value */
set_timer(&Expiretimer,atol(argv[1])*MSPHOUR); /* set timer duration */
start_timer(&Expiretimer);
return 0;
}
void
Expiretick(p)
void *p;
{
start_timer(&Expiretimer);
/* Spawn off the process */
newproc("Expiry", 1024, Expireprocess, 0, NULL, NULL, 0);
}
static void
Expireprocess(a,v1,v2)
int a;
void *v1, *v2;
{
char line[80];
int age = DEFAULT_AGE;
char *cp;
FILE *ctl;
if ((ctl = fopen(Expirefile, "r")) == NULLFILE) {
return;
}
/* read lines from the control file */
while(fgets(line, sizeof(line), ctl) != NULLCHAR) {
pwait(NULL); /* be nice */
if((*line == '#') || (*line == '\n')) /* comment or blank line */
continue;
rip(line);
/* terminate area name */
if((cp=strchr(line, ' ')) != NULLCHAR) {
/* there is age info */
*cp++ = '\0';
age = atoi(cp);
}
pwait(NULL); /* be nice */
expire(line,age);
}
fclose(ctl);
}
void
expire(filename,age)
char *filename;
int age;
{
char file[128], bckfile[128],*cp;
char buf[128];
int keep,copy,expired;
FILE *old;
FILE *new;
long pos;
time_t now;
time_t then;
struct tm t;
/* first replace all '.' and '\' with '/' */
for(cp=filename;*cp != '\0'; cp++)
if((*cp == '.') || (*cp == '\\'))
*cp = '/';
if (mlock(Mailspool,filename)) {
/* can't get a lock */
return;
}
/* now append the 'home dir' in front of name */
strcpy(file,Mailspool);
strcat(file,"/");
strcat(file, filename);
/* get the name for the backup file */
strcpy(bckfile,file);
strcat(bckfile,".bak");
strcat(file,".txt");
/* rename the file */
unlink(bckfile);
if(rename(file,bckfile) == -1) {
rmlock(Mailspool, filename);
return;
}
/* open the backup file and the new txt file */
if((old = fopen(bckfile, "rt")) == NULLFILE) {
rmlock(Mailspool, filename);
return;
}
if((new = fopen(file, "wt")) == NULLFILE) {
rmlock(Mailspool, filename);
return;
}
time(&now);
copy = expired = 0;
pos=ftell(old);
while(fgets(buf,sizeof(buf),old) != NULLCHAR) {
pwait(NULL);
if (!strncmp(buf,"From ",5)) {
/* start of next message; at this point
* pos has the offset of the start of this line
*/
keep = copy = 0;
while(fgets(buf,sizeof(buf),old) != NULLCHAR) {
if(*buf == '\n')
break; /* end of headers */
if(htype(buf) == DATE) {
/* find age from ARPA style date */
/* check to see if there is a "Day, " field */
if((cp=strchr(buf,',')) != NULLCHAR) {
/* probably standard ARPA style header */
cp = &buf[11]; /* get past header and DAY field */
} else {
/* probably a NNTP style message, that has no
* "Day, " part in the date line
*/
cp = &buf[6];
}
/* now we should be at the start of the
* "14 Apr 92 08:14:32" string
*/
if(strlen(cp) < 17) /* Too short */
break;
t.tm_mday = atoi(cp);
if(*(++cp) != ' ')
++cp;
++cp;
for(t.tm_mon=0; t.tm_mon < 12; t.tm_mon++)
if(strnicmp(Months[t.tm_mon],cp,3) == 0)
break;
if(t.tm_mon == 12)
break; /* invalid */
t.tm_year = atoi(cp+4);
t.tm_hour = atoi(cp+7);
t.tm_min = atoi(cp+10);
t.tm_sec = atoi(cp+13);
/*
printf("%d %d %d, %d %d %d\n",
t.tm_mday,t.tm_mon,t.tm_year,t.tm_hour,t.tm_min,t.tm_sec);
*/
if((then=mktime(&t)) == -1)
break; /* invalid, delete */
/* Now check against age */
if(now-then < (age*86400L))
keep = 1;
break;
}
}
if(keep) {
/* rewind to start of this message,
* write from-line and copy the rest
*/
fseek(old,pos,SEEK_SET);
fgets(buf,sizeof(buf),old);
fputs(buf,new);
copy = 1;
} else
expired++;
} else { /* Any none 'from' line */
if(copy)
/* we're in the middle of copying a message */
fputs(buf,new);
}
pos=ftell(old);
}
fclose(new);
fclose(old);
rmlock(Mailspool,filename);
if(expired)
log(-1,"Expired: %d in %s",expired,filename);
}
/******************************************************************/
/* This program will deleted old BID's from the history file,
* after making a backup copy.
*
* Eg. 'oldbids 24 30' will try to delete all bids older then 30 days
* every 24 hours.
* 'oldbids now' will do it now, with set value of age.
*
* Copyright 1992, Johan. K. Reinalda, WG7J/PA3DIS
* email : johan@ece.orst.edu
* packet: wg7j@wg7j.or.usa.na
*
* Any part of this source may be freely distributed for none-commercial,
* amateur radio use only, as long as credit is given to the author.
*
* v1.0 920325
*/
static struct timer Oldbidtimer;
static int Oldbid_age = 30;
static
void
Oldbidtick(p)
void *p;
{
int expired = 0;
char *cp;
FILE *old, *new;
time_t now;
time_t age;
time_t bidtime;
#define LEN 80
char oldfile[LEN];
char buf[LEN];
stop_timer(&Oldbidtimer);
/* delete a previous backup and rename current history file */
strcpy(oldfile,Historyfile);
strcat(oldfile,".bak");
unlink(oldfile);
if(rename(Historyfile,oldfile) == -1) {
tputs("oldbid: can't rename history file\n");
return;
}
/* open backup for reading, create new history file */
if((old = fopen(oldfile,"rt")) == NULL) {
tputs("oldbid: error opening history.bak\n");
return;
}
if((new = fopen(Historyfile,"wt")) == NULL) {
tputs("oldbid: error creating history file\n");
return;
}
now = time(&now);
age = (time_t)(Oldbid_age*86400L);
while(fgets(buf,LEN,old) != NULL) {
if((cp=strchr(buf,'\n')) != NULLCHAR)
*cp = '\0';
if((cp=strchr(buf,' ')) != NULLCHAR) {
/*found one with timestamp*/
*cp = '\0';
cp++; /* now points to timestamp */
if((bidtime = atol(cp)) == 0L)
/*something wrong, re-stamp */
fprintf(new,"%s %ld\n",buf,now);
else {
/* Has this one expired yet ? */
if(now - bidtime < age)
fprintf(new,"%s %ld\n",buf,bidtime);
else
expired++;
}
} else {
/* This is an old one without time stamp,
* add to the new file with current time as timestamp
*/
fprintf(new,"%s %ld\n",buf,now);
}
}
fclose(old);
fclose(new);
if(expired)
log(-1,"Oldbids: %d expired",expired);
start_timer(&Oldbidtimer);
return;
}
int
#ifdef PROTOTYPES
dooldbids(int argc,char **argv,void *p)
#else
dooldbids(argc,argv,p)
int argc;
char *argv[];
void *p;
#endif
{
if(argc < 2){
tprintf("timer: %lu/%lu hrs; age: %d days\n",
read_timer(&Oldbidtimer)/MSPHOUR,
dur_timer(&Oldbidtimer)/MSPHOUR,
Oldbid_age);
return 0;
}
if(*argv[1] == 'n') {
Oldbidtick(NULL);
return 0;
}
/* set the timer */
stop_timer(&Oldbidtimer); /* Just in case */
Oldbidtimer.func = (void (*)__FARGS((void*)))Oldbidtick;/* what to call on timeout */
Oldbidtimer.arg = NULL; /* dummy value */
set_timer(&Oldbidtimer,atol(argv[1])*MSPHOUR); /* set timer duration */
if(argc > 2)
Oldbid_age = atoi(argv[2]);
Oldbidtick(NULL); /* Do one now and start it all!*/
return 0;
}
#endif /* EXPIRE */